﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WikiTrailCreator.TrailData;
using WikiTrailCreator.MultiTextbox;
using WikiTrailCreator.TrailImages;
using WikiTrailCreator.Properties;
using System.Net;
using System.IO;
/* Comments! */
using System.Collections.Specialized;
using WikiTrailCreator.WikiGeneration;

namespace WikiTrailCreator
{
    public partial class FormMain : Form
    {
        private bool m_bIsSaved = false;
        private string m_strFilePath = null;

        public FormMain()
        {
            InitializeComponent();

            ucPhotoGalleryGroup1.ListenToGlobalGallery();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Merge problem:
            this.Close();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox aboutBox = new AboutBox();
            aboutBox.ShowDialog(this);
            aboutBox.Dispose();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Show the settings dialog:
            FormSettings formSettings = new FormSettings();
            formSettings.ShowDialog(this);
            formSettings.Dispose();
        }

        /// <summary>
        /// Pushes form data into a trail object.
        /// </summary>
        /// <returns></returns>
        private Trail FormDataToObject()
        {
            Trail trail = new Trail();

            this.ValidateChildren(); // Should make sure everything is validated first...

            // General
            trail.TrailName = textBoxTrailName.Text;
            trail.WikiCategory = textBoxWikiCategory.Text;

            // Summary Section
            trail.Summary.Difficulty = (comboBoxDifficulty.Text == null) ? "" : comboBoxDifficulty.Text;
            trail.Summary.Length = textBoxLength.Text;
            trail.Summary.NumDaysToHike = textBoxEffortDays.Text;
            trail.Summary.NumHoursToHike = textBoxEffortHrs.Text;
            trail.Summary.Snapshot = ucTBSummary.TextBoxContents;
            trail.Summary.Navigation = ucTBNavigation.TextBoxContents;
            trail.Summary.Shelter = ucTBShelter.TextBoxContents;
            trail.Summary.Season = ucTBSeason.TextBoxContents;

            foreach (MultiTextboxItem itemWithText in ucMTBDangersAnnoy.Items)
            {
                Danger danger = new Danger();
                danger.Name = itemWithText.ItemName;
                danger.Description = itemWithText.ItemText;
                trail.Summary.AddDanger(danger);
            }

            trail.Summary.Costs = ucTBCosts.TextBoxContents;

            foreach (MultiTextboxItem itemWithText in ucMTBTips.Items)
            {
                Tip tip = new Tip();
                tip.TipText = itemWithText.ItemName;
                trail.Summary.AddTip(tip);
            }

            // Landmarks
            foreach (MultiTextboxItem itemWithText in ucMTBLandmarks.Items)
            {
                Landmark landmark = new Landmark();
                landmark.Name = itemWithText.ItemName;
                landmark.Description = itemWithText.ItemText;
                trail.Landmarks.AddLandmark(landmark);
            }

            // Maps
            trail.Maps.Purchased = ucTBPurchased.TextBoxContents;
            trail.Maps.Online = ucTBOnlineMap.TextBoxContents;

            // Getting There
            foreach (MultiTextboxItem itemWithText in ucMTBGettingThere.Items)
            {
                GettingThereOption gettingThereOption = new GettingThereOption();
                gettingThereOption.OptionName = itemWithText.ItemName;
                gettingThereOption.OptionDescription = itemWithText.ItemText;
                trail.GettingThere.AddGettingThereOption(gettingThereOption);
            }

            // Gallery Photos
            ImageGallery imageGallery = ucPhotoGalleryGroup1.ImagesInGallery;
            foreach (TrailImage trailImage in imageGallery.Images)
            {
                LocalImage localImage = new LocalImage();
                localImage.InternalId = trailImage.Id;
                localImage.DisplayText = trailImage.DisplayText;
                localImage.LocalPath = trailImage.LocalPath;
                localImage.PageText = trailImage.PageText;
                localImage.GalleryCaption = trailImage.GalleryCaption;

                trail.PhotoGallery.AddPhotoReferrenced(localImage);
            }

            // Conditions
            trail.Conditions.ConditionsText = ucTBConditions.TextBoxContents;

            // Related Links
            foreach (MultiTextboxItem itemWithText in ucMTBLinks.Items)
            {
                RelatedLink relatedLink = new RelatedLink();
                relatedLink.Name = itemWithText.ItemName;
                relatedLink.URL = itemWithText.ItemText;
                trail.RelatedLinks.AddRelatedLink(relatedLink);
            }

            // All Photos
            ImageGallery globalImageGallery = GlobalImageGalleryContainer.Instance;
            foreach (TrailImage trailImage in globalImageGallery.Images)
            {
                LocalImage localImage = new LocalImage();
                localImage.InternalId = trailImage.Id;
                localImage.DisplayText = trailImage.DisplayText;
                localImage.LocalPath = trailImage.LocalPath;
                localImage.PageText = trailImage.PageText;
                localImage.GalleryCaption = trailImage.GalleryCaption;

                trail.AddTrailImage(localImage);
            }

            return trail;
        }

        /// <summary>
        /// Pushes form data into a trail object.
        /// </summary>
        /// <returns></returns>
        private void ObjectDataToForm(Trail trail)
        {
            // General
            textBoxTrailName.Text = trail.TrailName;
            textBoxWikiCategory.Text = trail.WikiCategory;

            // Summary Section
            comboBoxDifficulty.Text = trail.Summary.Difficulty;
            textBoxLength.Text = trail.Summary.Length;
            textBoxEffortDays.Text = trail.Summary.NumDaysToHike;
            textBoxEffortHrs.Text = trail.Summary.NumHoursToHike;
            ucTBSummary.TextBoxContents = trail.Summary.Snapshot;
            ucTBNavigation.TextBoxContents = trail.Summary.Navigation;
            ucTBShelter.TextBoxContents = trail.Summary.Shelter;
            ucTBSeason.TextBoxContents = trail.Summary.Season;

            List<MultiTextboxItem> ucMTBDangersAnnoyItems = new List<MultiTextboxItem>();
            foreach (Danger danger in trail.Summary.DangersOrAnnoyances)
            {
                ucMTBDangersAnnoyItems.Add(new MultiTextboxItem(danger.Name, danger.Description));
            }
            ucMTBDangersAnnoy.Items = ucMTBDangersAnnoyItems.ToArray();

            ucTBCosts.TextBoxContents = trail.Summary.Costs;

            List<MultiTextboxItem> ucMTBTipsItems = new List<MultiTextboxItem>();
            foreach (Tip tip in trail.Summary.Tips)
            {
                ucMTBTipsItems.Add(new MultiTextboxItem(tip.TipText, ""));
            }
            ucMTBTips.Items = ucMTBTipsItems.ToArray();

            // Landmarks
            List<MultiTextboxItem> ucMTBLandmarksItems = new List<MultiTextboxItem>();
            foreach (Landmark landmark in trail.Landmarks.Landmarks)
            {
                ucMTBLandmarksItems.Add(new MultiTextboxItem(landmark.Name, landmark.Description));
            }
            ucMTBLandmarks.Items = ucMTBLandmarksItems.ToArray();

            // Maps
            ucTBPurchased.TextBoxContents = trail.Maps.Purchased;
            ucTBOnlineMap.TextBoxContents = trail.Maps.Online;

            // Getting There
            List<MultiTextboxItem> ucMTBGettingThereItems = new List<MultiTextboxItem>();
            foreach (GettingThereOption gettingThereOption in trail.GettingThere.GettingThereOptions)
            {
                ucMTBGettingThereItems.Add(new MultiTextboxItem(gettingThereOption.OptionName, gettingThereOption.OptionDescription));
            }
            ucMTBGettingThere.Items = ucMTBGettingThereItems.ToArray();

            // Clear the gallery first...
            ucPhotoGalleryGroup1.ImagesInGallery = null;

            // All Photos (need to be loaded before the gallery photos)
            List<TrailImage> allTrailImages = new List<TrailImage>();
            foreach (LocalImage localImage in trail.AllTrailImages)
            {
                TrailImage trailImage = new TrailImage(localImage.InternalId, localImage.DisplayText, localImage.LocalPath);
                trailImage.GalleryCaption = localImage.GalleryCaption;
                trailImage.PageText = localImage.PageText;

                allTrailImages.Add(trailImage);
            }
            GlobalImageGalleryContainer.Instance.Images = allTrailImages.ToArray();

            // Gallery Photos
            List<TrailImage> galleryTrailImages = new List<TrailImage>();
            foreach (LocalImage localImage in trail.PhotoGallery.PhotosReferrenced)
            {
                TrailImage trailImage = new TrailImage(localImage.InternalId, localImage.DisplayText, localImage.LocalPath);
                trailImage.GalleryCaption = localImage.GalleryCaption;
                trailImage.PageText = localImage.PageText;

                galleryTrailImages.Add(trailImage);
            }
            ucPhotoGalleryGroup1.ImagesInGallery = new ImageGallery(galleryTrailImages.ToArray());

            // Conditions
            ucTBConditions.TextBoxContents = trail.Conditions.ConditionsText;

            // Related Links
            List<MultiTextboxItem> ucMTBLinksItems = new List<MultiTextboxItem>();
            foreach (RelatedLink relatedLink in trail.RelatedLinks.RelatedLinks)
            {
                ucMTBLinksItems.Add(new MultiTextboxItem(relatedLink.Name, relatedLink.URL));
            }
            ucMTBLinks.Items = ucMTBLinksItems.ToArray();
        }

        private void imagesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormTrailImages formTrailImages = new FormTrailImages();
            formTrailImages.ShowDialog();
            formTrailImages.Dispose();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool bCanceledSave = false;
            
            PromptForSave(out bCanceledSave);

            if (!bCanceledSave)
            {
                ClearAll();
            }
        }

        private void ClearAll()
        {
            // General
            textBoxTrailName.Text = "";
            textBoxWikiCategory.Text = "";

            // Summary Section
            comboBoxDifficulty.Text = "";
            textBoxLength.Text = "";
            textBoxEffortDays.Text = "";
            textBoxEffortHrs.Text = "";
            ucTBSummary.TextBoxContents = "";
            ucTBNavigation.TextBoxContents = "";
            ucTBShelter.TextBoxContents = "";
            ucTBSeason.TextBoxContents = "";

            ucMTBDangersAnnoy.Items = null;

            ucTBCosts.TextBoxContents = "";

            ucMTBTips.Items = null;

            // Landmarks
            ucMTBLandmarks.Items = null;

            // Maps
            ucTBPurchased.TextBoxContents = "";
            ucTBOnlineMap.TextBoxContents = "";

            // Getting There
            ucMTBGettingThere.Items = null;

            // Gallery Photos
            ucPhotoGalleryGroup1.ImagesInGallery = new ImageGallery();

            // Conditions
            ucTBConditions.TextBoxContents = "";

            // Related Links
            ucMTBLinks.Items = null;

            // All Photos
            GlobalImageGalleryContainer.Instance.Images = null;

            // Other cleanup stuff when clearing...
            m_strFilePath = null;
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_strFilePath == null)
            {
                ShowSaveDialog();
            }
            else
            {
                SaveFile(m_strFilePath);
            }
        }

        private DialogResult ShowSaveDialog()
        {
            DialogResult dialogResult = saveFileDialog1.ShowDialog();

            if (dialogResult == DialogResult.OK)
            {
                string fileName = saveFileDialog1.FileName;

                SaveFile(fileName);
            }

            return dialogResult;
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool bCanceledSave = false;
            PromptForSave(out bCanceledSave);

            if (!bCanceledSave)
            {
                DialogResult dialogResult = openFileDialog1.ShowDialog();

                if (dialogResult == DialogResult.OK)
                {
                    string fileName = openFileDialog1.FileName;

                    LoadFile(fileName);
                }
            }
        }

        private void SaveFile(string filePath)
        {
            this.Cursor = Cursors.WaitCursor;
            this.Refresh();

            try
            {
                Trail trailToSave = FormDataToObject();
                Trail.Save(filePath, trailToSave);
                m_strFilePath = filePath;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void LoadFile(string filePath)
        {
            this.Cursor = Cursors.WaitCursor;
            this.Refresh();

            try
            {
                Trail loadedTrail = Trail.Load(filePath);
                ObjectDataToForm(loadedTrail);
                m_strFilePath = filePath;
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool bCanceledSave = false;
            PromptForSave(out bCanceledSave);

            if (bCanceledSave)
            {
                e.Cancel = true;
            }
        }

        /// <summary>
        /// Prompts the user if they want to save the current trail.
        /// </summary>
        /// <returns>Whether or not the save process was canceled.</returns>
        private void PromptForSave(out bool bCanceledSave)
        {
            // Prompt for save...
            if (!m_bIsSaved)
            {
                DialogResult dialogResult = MessageBox.Show(this, "Would you like to save your changes?", "Warning", MessageBoxButtons.YesNoCancel);

                if (dialogResult == DialogResult.Yes)
                {
                    DialogResult saveDialogResult = DialogResult.OK;

                    if (m_strFilePath == null)
                    {
                        saveDialogResult = ShowSaveDialog();
                    }
                    else
                    {
                        SaveFile(m_strFilePath);
                    }

                    if (saveDialogResult != DialogResult.OK)
                    {
                        bCanceledSave = true;
                        return;
                    }
                }
                else if (dialogResult == DialogResult.Cancel)
                {
                    bCanceledSave = true;
                    return;
                }
            }

            bCanceledSave = false;
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowSaveDialog();
        }

        private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            Settings.Default.Save();
        }

        private void generateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Trail trail = FormDataToObject();

            FormWikiGeneration formWikiGeneration = new FormWikiGeneration();
            formWikiGeneration.SetTrail(trail);

            formWikiGeneration.ShowDialog();
        }
    }
}
